package com.tianbao54.concurrent.condition;

import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class ClientWithCondition {

    public static void main(String[] args) {

        WareHouse house = new WareHouse();
        ExecutorService service = Executors.newFixedThreadPool(10);
        service.submit(() -> {
            while (true) {
                house.put(new Product());
                TimeUnit.SECONDS.sleep(1);
            }
        });

        service.submit(() -> {
            while (true) {
                house.get();
                TimeUnit.SECONDS.sleep(2);
            }
        });
    }

    static class WareHouse {

        private static final int MAX_SIZE = 10;
        private static final Product[] products = new Product[MAX_SIZE];
        private static final AtomicInteger currentSize = new AtomicInteger(0);
        private static final ReentrantLock look = new ReentrantLock();
        private Condition full = look.newCondition();
        private Condition empty = look.newCondition();

        public void put (Product product) {

            look.lock();
            try {
                while (currentSize.get() == MAX_SIZE) {
                    System.out.println("仓库已满，等待取走产品。");
                    full.await();
                }
                System.out.println("放入新的产品：" + product + " 当前仓库剩余容量：" + (MAX_SIZE - currentSize.get()));
                products[currentSize.getAndIncrement()] = product;
                empty.signalAll();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                look.unlock();
            }
        }

        public Product get () {

            look.lock();
            try {
                while (currentSize.get() == 0) {
                    System.out.println("仓库已空，等待放入新的产品。");
                    empty.await();
                }
                full.signalAll();
                Product product = products[currentSize.decrementAndGet()];
                System.out.println("取出一个新的产品：" + product + " 当前仓库剩余容量：" + (MAX_SIZE - currentSize.get()));
                return product;
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                look.unlock();
            }
            return null;
        }

    }

    static class Product {
        private String id;

        Product() {
            this.id = UUID.randomUUID().toString();
        }

        @Override
        public String toString() {
            return "id : " + id;
        }
    }
}
